package handler

import (
	myerror "CodeCover/internal/errors"
	"CodeCover/internal/models"
	"CodeCover/internal/service"
	"errors"
	"fmt"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"gorm.io/gorm"
)

type UserHandler struct {
	service *service.UserService
}

func NewUserHandler(svc *service.UserService) *UserHandler {
	return &UserHandler{service: svc}
}

func (h *UserHandler) Register(ctx *gin.Context) {
	var user models.User
	if err := ctx.ShouldBind(&user); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
		return
	}
	if err := h.service.RegisterUser(ctx.Request.Context(), &user); err != nil {
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}
	ctx.JSON(http.StatusCreated, gin.H{
		"message": "注册成功！",
	})
}

func (h *UserHandler) Login(ctx *gin.Context) {
	type LoginForm struct {
		Username string `form:"username" binding:"required"`
		Password string `form:"password" binding:"required"`
	}
	var form LoginForm
	if err := ctx.ShouldBind(&form); err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"code":    400,
			"message": "invalid request",
		})
		return
	}

	var user models.User
	user.UserName = form.Username
	user.Password = form.Password
	if existedUser, err := h.service.Login(ctx.Request.Context(), &user); err != nil {
		fmt.Println(myerror.FormatErrorLog(err))
		if errors.Is(err, gorm.ErrRecordNotFound) {
			ctx.JSON(http.StatusUnauthorized, gin.H{"error": "用户不存在" + err.Error()})
			return
		}

		if existedUser.Password != user.Password {
			ctx.JSON(http.StatusUnauthorized, gin.H{"error": "密码错误" + err.Error()})
			return
		}
		ctx.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
		return
	}

	ctx.SetCookie("username", user.UserName, 3600, "/", "", false, false)

	fmt.Println("login success")
	ctx.JSON(http.StatusOK, gin.H{
		"message": "login success",
	})

}

func (h *UserHandler) ApplyToken(ctx *gin.Context) {
	type formData struct {
		Username string `form:"username"`
	}
	var form formData
	ctx.ShouldBind(&form)

	if form.Username == "" {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"error": "BadRequest",
		})
		return
	}
	token, err := h.service.ApplyToken(ctx.Request.Context(), form.Username)
	if err != nil {
		ctx.JSON(http.StatusBadRequest, gin.H{
			"error": err,
		})
		return
	}

	ctx.JSON(http.StatusOK, gin.H{
		"token": token,
	})

}

func (h *UserHandler) LoginOut(ctx *gin.Context) {
	expiration := time.Now().Add(-1 * time.Hour)
	ctx.SetCookie("username", "", int(expiration.Unix()), "/", "", false, true)
	ctx.JSON(http.StatusOK, gin.H{"message": "Cookie 清除成功"})
}
